'use client';
import type { FC } from 'react';
import React, { useState } from 'react';
import useSWR from 'swr';
import { ArrowLeftIcon } from '@heroicons/react/24/solid';
import { createContext, useContext } from 'use-context-selector';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';
import { omit } from 'lodash-es';
import { OperationAction, StatusItem } from '../list';
import s from '../style.module.css';
import Completed from './completed';
import Embedding from './embedding';
import Metadata from './metadata';
import SegmentAdd, { ProcessStatus } from './segment-add';
import BatchModal from './batch-modal';
import style from './style.module.css';
import cn from '@/utils/classnames';
import Divider from '@/app/components/base/divider';
import Loading from '@/app/components/base/loading';
import type { MetadataType } from '@/service/datasets';
import { checkSegmentBatchImportProgress, fetchDocumentDetail, segmentBatchImport } from '@/service/datasets';
import { ToastContext } from '@/app/components/base/toast';
import type { DocForm } from '@/models/datasets';
import { useDatasetDetailContext } from '@/context/dataset-detail';
import FloatRightContainer from '@/app/components/base/float-right-container';
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints';

export const DocumentContext = createContext<{ datasetId?: string; documentId?: string; docForm: string }>({ docForm: '' });

type DocumentTitleProps = {
  extension?: string;
  name?: string;
  iconCls?: string;
  textCls?: string;
  wrapperCls?: string;
};

export const DocumentTitle: FC<DocumentTitleProps> = ({ extension, name, iconCls, textCls, wrapperCls }) => {
  const localExtension = extension?.toLowerCase() || name?.split('.')?.pop()?.toLowerCase();
  return (
    <div className={cn('flex items-center justify-start flex-1', wrapperCls)}>
      <div className={cn(s[`${localExtension || 'txt'}Icon`], style.titleIcon, iconCls)}></div>
      <span className={cn('font-semibold text-lg text-gray-900 ml-1', textCls)}> {name || '--'}</span>
    </div>
  );
};

type Props = {
  datasetId: string;
  documentId: string;
};

const DocumentDetail: FC<Props> = ({ datasetId, documentId }) => {
  const router = useNavigate();
  const { t } = useTranslation();

  const media = useBreakpoints();
  const isMobile = media === MediaType.mobile;

  const { notify } = useContext(ToastContext);
  const { dataset } = useDatasetDetailContext();
  const embeddingAvailable = !!dataset?.embedding_available;
  const [showMetadata, setShowMetadata] = useState(!isMobile);
  const [newSegmentModalVisible, setNewSegmentModalVisible] = useState(false);
  const [batchModalVisible, setBatchModalVisible] = useState(false);
  const [importStatus, setImportStatus] = useState<ProcessStatus | string>();
  const showNewSegmentModal = () => setNewSegmentModalVisible(true);
  const showBatchModal = () => setBatchModalVisible(true);
  const hideBatchModal = () => setBatchModalVisible(false);
  const resetProcessStatus = () => setImportStatus('');
  const checkProcess = async (jobID: string) => {
    try {
      const res = await checkSegmentBatchImportProgress({ jobID });
      setImportStatus(res.job_status);
      if (res.job_status === ProcessStatus.WAITING || res.job_status === ProcessStatus.PROCESSING)
        setTimeout(() => checkProcess(res.job_id), 2500);
      if (res.job_status === ProcessStatus.ERROR) notify({ type: 'error', message: `${t('datasetDocuments.list.batchModal.runError')}` });
    } catch (e: any) {
      notify({ type: 'error', message: `${t('datasetDocuments.list.batchModal.runError')}${'message' in e ? `: ${e.message}` : ''}` });
    }
  };
  const runBatch = async (csv: File) => {
    const formData = new FormData();
    formData.append('file', csv);
    try {
      const res = await segmentBatchImport({
        url: `/datasets/${datasetId}/documents/${documentId}/segments/batch_import`,
        body: formData,
      });
      setImportStatus(res.job_status);
      checkProcess(res.job_id);
    } catch (e: any) {
      notify({ type: 'error', message: `${t('datasetDocuments.list.batchModal.runError')}${'message' in e ? `: ${e.message}` : ''}` });
    }
  };

  const {
    data: documentDetail,
    error,
    mutate: detailMutate,
  } = useSWR(
    {
      action: 'fetchDocumentDetail',
      datasetId,
      documentId,
      params: { metadata: 'without' as MetadataType },
    },
    (apiParams) => fetchDocumentDetail(omit(apiParams, 'action')),
  );

  const {
    data: documentMetadata,
    error: metadataErr,
    mutate: metadataMutate,
  } = useSWR(
    {
      action: 'fetchDocumentDetail',
      datasetId,
      documentId,
      params: { metadata: 'only' as MetadataType },
    },
    (apiParams) => fetchDocumentDetail(omit(apiParams, 'action')),
  );

  const backToPrev = () => {
    router(`/datasets/${datasetId}/documents`);
  };

  const isDetailLoading = !documentDetail && !error;
  const isMetadataLoading = !documentMetadata && !metadataErr;

  const embedding = ['queuing', 'indexing', 'paused'].includes((documentDetail?.display_status || '').toLowerCase());

  const handleOperate = (operateName?: string) => {
    if (operateName === 'delete') backToPrev();
    else detailMutate();
  };

  return (
    <DocumentContext.Provider value={{ datasetId, documentId, docForm: documentDetail?.doc_form || '' }}>
      <div className="flex flex-col h-full">
        <div className="flex min-h-16 border-b-gray-100 border-b items-center p-4 justify-between flex-wrap gap-y-2">
          <div
            onClick={backToPrev}
            className={
              'shrink-0 rounded-full w-8 h-8 flex justify-center items-center border-gray-100 cursor-pointer border hover:border-gray-300 shadow-[0px_12px_16px_-4px_rgba(16,24,40,0.08),0px_4px_6px_-2px_rgba(16,24,40,0.03)]'
            }
          >
            <ArrowLeftIcon className="text-primary-600 fill-current stroke-current h-4 w-4" />
          </div>
          <Divider className="!h-4" type="vertical" />
          <DocumentTitle extension={documentDetail?.data_source_info?.upload_file?.extension} name={documentDetail?.name} />
          <div className="flex items-center flex-wrap gap-y-2">
            <StatusItem status={documentDetail?.display_status || 'available'} scene="detail" errorMessage={documentDetail?.error || ''} />
            {embeddingAvailable && documentDetail && !documentDetail.archived && (
              <SegmentAdd
                importStatus={importStatus}
                clearProcessStatus={resetProcessStatus}
                showNewSegmentModal={showNewSegmentModal}
                showBatchModal={showBatchModal}
              />
            )}
            <OperationAction
              scene="detail"
              embeddingAvailable={embeddingAvailable}
              detail={{
                name: documentDetail?.name || '',
                enabled: documentDetail?.enabled || false,
                archived: documentDetail?.archived || false,
                id: documentId,
                data_source_type: documentDetail?.data_source_type || '',
                doc_form: documentDetail?.doc_form || '',
              }}
              datasetId={datasetId}
              onUpdate={handleOperate}
              className="!w-[216px]"
            />
            <button
              className={cn(style.layoutRightIcon, showMetadata ? style.iconShow : style.iconClose)}
              onClick={() => setShowMetadata(!showMetadata)}
            />
          </div>
        </div>
        <div className="flex flex-row flex-1" style={{ height: 'calc(100% - 4rem)' }}>
          {isDetailLoading ? (
            <Loading type="app" />
          ) : (
            <div className={`h-full w-full flex flex-col ${embedding ? 'px-6 py-3 sm:py-12 sm:px-16' : 'pb-[30px] pt-3 px-6'}`}>
              {embedding ? (
                <Embedding detail={documentDetail} detailUpdate={detailMutate} />
              ) : (
                <Completed
                  embeddingAvailable={embeddingAvailable}
                  showNewSegmentModal={newSegmentModalVisible}
                  onNewSegmentModalChange={setNewSegmentModalVisible}
                  importStatus={importStatus}
                  archived={documentDetail?.archived}
                />
              )}
            </div>
          )}
          <FloatRightContainer
            showClose
            isOpen={showMetadata}
            onClose={() => setShowMetadata(false)}
            isMobile={isMobile}
            panelClassname="!justify-start"
            footer={null}
          >
            <Metadata
              docDetail={
                {
                  ...documentDetail,
                  ...documentMetadata,
                  doc_type: documentMetadata?.doc_type === 'others' ? '' : documentMetadata?.doc_type,
                } as any
              }
              loading={isMetadataLoading}
              onUpdate={metadataMutate}
            />
          </FloatRightContainer>
        </div>
        <BatchModal
          isShow={batchModalVisible}
          onCancel={hideBatchModal}
          onConfirm={runBatch}
          docForm={documentDetail?.doc_form as DocForm}
        />
      </div>
    </DocumentContext.Provider>
  );
};

export default DocumentDetail;
